import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:lib_core/logger/gt_logger.dart';
import 'package:lib_core/model/lib_core_event_model.dart';

/// Author: Shper
/// Created: 2023/7/9

typedef GTEventCenterCallback = void Function(String actionType, String actionName, Map<String, dynamic>? data);

class GTLibCoreEventChannel {

  GTLibCoreEventChannel._();

  /// 接收侧统一消息通道
  static const EventChannel _eventChannel = EventChannel('com.gateio.flutter.lib_core.EventChannel');

  static final Map<String, List<GTEventCenterCallback>>  _listenerMap = {};

  /// 开始监听
  static void startListen() {
    GTLogger.debug("GTEventCenter start to listener message.");

    // 监听原生侧 消息通知
    _eventChannel.receiveBroadcastStream().listen((event) {
      if (event == null) {
        GTLogger.debug("GTEventCenter: The Event message is null.");
        return;
      }
      GTLogger.debug("GTEventCenter listen: $event");

      // 解析数据
      Map<String, dynamic> paramsMap = json.decode(event);
      if (paramsMap.isEmpty) {
        GTLogger.debug("GTEventCenter: The Event message is empty.");
        return;
      }
      var eventModel = GTLiCoreEventModel.fromJson(paramsMap);
      if (eventModel.isInvalid()) {
        GTLogger.debug("GTEventCenter: The Event message is invalid.");
        return;
      }
      // 合格消息进行分发消息
      _dispatchListens(eventModel);
    });
  }

  /// 增加监听具体分类的通知
  static addListener(Enum action, GTEventCenterCallback callback) {
    var actionKey = _generateActionKeyByEnum(action);
    GTLogger.debug("GTEventCenter addListener - actionKey: $actionKey");

    var callbackList = _listenerMap[actionKey] ??= [];
    callbackList.add(callback);
    _listenerMap[actionKey] = callbackList;
  }

  /// 增加 监听全部分类的通知
  static addListenerByList(List<Enum> actions, GTEventCenterCallback callback) {
    for (var action in actions) {
      addListener(action, callback);
    }
  }

  // 分发消息
  static _dispatchListens(GTLiCoreEventModel eventModel) {
    var actionKey = _generateActionKey(eventModel.actionType, eventModel.actionName);
    // 先分发具体消息
    var callbackList = _listenerMap[actionKey] ??= [];
    GTLogger.debug("GTEventCenter dispatchListens action: $actionKey; callbackList: ${callbackList.length}");

    for (var element in callbackList) {
      try {
        element.call(eventModel.actionType, eventModel.actionName, eventModel.data);
      } catch (e) {
        GTLogger.error(e);
      }
    }
  }

  /// 根据 枚举生成 action key
  static String _generateActionKeyByEnum(Enum action) {
    return "${action.runtimeType}.${action.name}";
  }

  /// 根据 枚举生成 action key
  static String _generateActionKey(String actionType, String actionName) {
    return "$actionType.$actionName";
  }

}